package com.yonyou.common.service.messagecenter.rabbitmq.service;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.yonyou.common.service.messagecenter.dao.TtResendMessageMapper;
import com.yonyou.common.service.messagecenter.rabbitmq.MessageProducer;
import com.yonyou.common.service.messagecenter.rabbitmq.entity.MessageProtocol;
import com.yonyou.common.service.messagecenter.rabbitmq.entity.TtMessageHistoryConsumer;
import com.yonyou.common.service.messagecenter.rabbitmq.entity.TtResendMessage;
import com.yonyou.common.service.messagecenter.util.MqConsts;

import tk.mybatis.mapper.entity.Example;

@Service
public class ResendMessageService {

	@Autowired
	private TtResendMessageMapper resendMessageMapper;
	@Autowired
	private MessageProducer producer;

    @Transactional(rollbackFor=Exception.class)
    public boolean insertResendMessage(TtMessageHistoryConsumer record,String data){
    	TtResendMessage message=this.getResendMessage(record.getSign(), record.getConsumer());
    	if(message==null){
    		message=new TtResendMessage();
	    	message.setAppid(record.getAppid());
	    	message.setBody(data);
	    	message.setCreateDate(new Date(System.currentTimeMillis()));
	    	message.setMessageid(record.getMessageid());
	    	message.setSign(record.getSign());
	    	message.setConsumer(record.getConsumer());
	    	message.setTryCount(0);
	    	message.setStatus(MqConsts.RESEND_STATUS_START);
	    	resendMessageMapper.insert(message);
    	}else{
    		message.setUpdateDate(new Date(System.currentTimeMillis()));
	    	resendMessageMapper.updateByPrimaryKeySelective(message);
    	}
    	return true;
    }
    @Transactional(rollbackFor=Exception.class)
    public boolean updateResendSuccessMessage(String sign,String consumer){
    	TtResendMessage record =this.getResendMessage(sign,consumer);
    	if(record==null) return true;
    	record.setStatus(MqConsts.RESEND_STATUS_FINISH);
    	record.setUpdateDate(new Date(System.currentTimeMillis()));
    	resendMessageMapper.updateByPrimaryKeySelective(record);
    	return true;
    }
    @Transactional(rollbackFor=Exception.class)
    public boolean updateResendDirectSuccessMessage(String sign,String consumer){
    	TtResendMessage record =this.getResendMessage(sign,consumer);
    	if(record==null) return true;
    	record.setStatus(MqConsts.RESEND_STATUS_DIRECT_FINISH);
    	record.setUpdateDate(new Date(System.currentTimeMillis()));
    	resendMessageMapper.updateByPrimaryKeySelective(record);
    	return true;
    }
    @Transactional(rollbackFor=Exception.class)
    public boolean updateResendSuccessMessage(TtResendMessage record){
    	record.setStatus(MqConsts.RESEND_STATUS_FINISH);
    	record.setUpdateDate(new Date(System.currentTimeMillis()));
    	resendMessageMapper.updateByPrimaryKeySelective(record);
    	return true;
    }
    @Transactional(rollbackFor=Exception.class)
    public boolean updateResendMessage(TtResendMessage record){
    	record.setStatus(MqConsts.RESEND_STATUS_SEND);
    	record.setTryCount(record.getTryCount()+1);
    	record.setUpdateDate(new Date(System.currentTimeMillis()));
    	resendMessageMapper.updateByPrimaryKeySelective(record);
    	return true;
    }
    @Transactional(rollbackFor=Exception.class)
    public boolean updateResendFailMessage(TtResendMessage record){
    	record.setStatus(MqConsts.RESEND_STATUS_FAIL);
    	record.setUpdateDate(new Date(System.currentTimeMillis()));
    	resendMessageMapper.updateByPrimaryKeySelective(record);
    	return true;
    }
    public TtResendMessage getResendMessage(String sign,String consumer){
    	Example example = new Example(TtMessageHistoryConsumer.class);
    	example.createCriteria().andCondition("sign=", sign).andCondition("consumer=", consumer);
    	List<TtResendMessage> records=resendMessageMapper.selectByExample(example);
    	if(records.size()==0)
    		return null;
    	return records.get(0);
    }
    public List<TtResendMessage> getNeedResendMessage(String level){
/*    	Example example = new Example(TtMessageHistoryConsumer.class);
    	example.createCriteria().andCondition("(status!=", MqConsts.RESEND_STATUS_FINISH).
    		andCondition("(status!=)", MqConsts.RESEND_STATUS_FINISH)
    		.andCondition("tryCount<=", 10);
    	List<TtResendMessage> records=resendMessageMapper.selectByExample(example);*/
    	Map<String,Integer> map=this.getCondition(level);
    	List<TtResendMessage> records=resendMessageMapper.getNeedResendMessage(map);
    	return records;
    }
    public void resendMessage(String level){
    	List<TtResendMessage> list=this.getNeedResendMessage(level);
    	for(TtResendMessage e:list){
    		MessageProtocol message=new MessageProtocol();
    		message.setAppid(e.getAppid());
    		message.setMessagecontent(e.getBody());
    		message.setSign(e.getSign());
    		boolean r=producer.reSendMessage(MqConsts.DEFAULT_DIRECT_EXCHANGE, e.getConsumer(), message,true);
    		if(r){
    			this.updateResendMessage(e);
    		}else{
    			this.updateResendFailMessage(e);
    		}
    	}
    }
    private Map<String,Integer> getCondition(String level){
    	Map<String,Integer> map =new HashMap<String,Integer>();
    	if(level.equals(MqConsts.RESEND_MESSAGE_LEVEL_HIGH)){
        	map.put("minCount", 0);
        	map.put("maxCount", MqConsts.RESEND_MESSAGE_COUNT_HIGH);
    	}
    	if(level.equals(MqConsts.RESEND_MESSAGE_LEVEL_MEDIUM)){
        	map.put("minCount", MqConsts.RESEND_MESSAGE_COUNT_HIGH);
        	map.put("maxCount", MqConsts.RESEND_MESSAGE_COUNT_MEDIUM);
    	}
    	if(level.equals(MqConsts.RESEND_MESSAGE_LEVEL_LOW)){
        	map.put("minCount", MqConsts.RESEND_MESSAGE_COUNT_MEDIUM);
        	map.put("maxCount", MqConsts.RESEND_MESSAGE_COUNT_LOW);
    	}
    	if(level.equals(MqConsts.RESEND_MESSAGE_LEVEL_LOWER)){
        	map.put("minCount", MqConsts.RESEND_MESSAGE_COUNT_LOW);
        	map.put("maxCount", MqConsts.RESEND_MESSAGE_COUNT_LOWER);
    	}
    	return map;
    }
    
    
    
    /**
     * 重置重试次数
     * 
     * @param record
     * @return
     */
    @Transactional
    public boolean updateRetryCount(TtResendMessage record){
    	record.setTryCount(record.getTryCount());
    	record.setUpdateDate(new Date(System.currentTimeMillis()));
    	resendMessageMapper.updateByPrimaryKeySelective(record);
    	return true;
    }
    
    
    /**
     * 重发的记录表
     * 
     * @param page
     * @param pageSize
     * @param sign
     * @return
     */
    public PageInfo<TtResendMessage> getAllResendsByPage(int page,int pageSize,String sign){
    	Example example = new Example(TtResendMessage.class);
    	example.createCriteria()
    			.andCondition(StringUtils.isEmpty(sign)?"1=1":"sign='"+sign+"'");
    	example.orderBy("id").desc(); 
    	PageInfo<TtResendMessage> pages= PageHelper.startPage(page, pageSize).doSelectPageInfo(() -> resendMessageMapper.selectByExample(example));
    	
    	return pages;
    }
}
